package com.jcx.ldzj.config;

import com.alibaba.fastjson.JSONObject;
import com.jcx.ldzj.dao.RoleMenuRelationMapper;
import com.jcx.ldzj.dao.UserRoleRelationMapper;
import com.jcx.ldzj.emun.SystemCode;
import com.jcx.ldzj.entity.RoleMenuRelation;
import com.jcx.ldzj.entity.UserInfo;
import com.jcx.ldzj.entity.UserRoleRelation;
import com.jcx.ldzj.service.IUserInfoService;
import com.jcx.ldzj.utile.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统初始化数据
 */
@Component
public class UserConfig implements ApplicationRunner {

    @Autowired
    private IUserInfoService iUserInfoService;
    /**
     * 这里之所以调用mapper是因为会存在循环依赖问题，因为ApplicationRunner加载的时候spring还没有将对应的service加载完全
     * 当有循环依赖出现时，Bean中注入的bean不是最终的版本，而是spring 三级缓存中的第二级缓存引用。
     * 然而这个引用在完成bean注入后将发生改变。导致注入的bean跟最终生成的bean不是同一个。
     * 但关于ApplicationRunner中国接口具体在哪里加载的是属于springboot的源代码，这个还没看
     */
    @Autowired(required = false)
    private UserRoleRelationMapper userRoleRelationMapper;

    @Autowired(required = false)
    private RoleMenuRelationMapper roleMenuRelationMapper;
    @Autowired
    private RedisUtil redisclient;



    @Override
    public void run(ApplicationArguments args) throws Exception {
        this.setUserInfo();

    }
    /**
     * 将用户数据存储到缓存中
     */
    public void setUserInfo(){
        //存储权限，key为用户名
        Map<String, String> userMap=new HashMap<>();

        List<UserInfo> list = iUserInfoService.list();
        for (int i = 0; i < list.size(); i++) {
            UserInfo userInfo = list.get(i);
            //以用户名为区分，存储角色
            this.setRoles(userInfo);
            userMap.put(userInfo.getUserName(),JSONObject.toJSONString(userInfo));
        }
        //用户信息
        redisclient.hPutAll(SystemCode.USER_MAP,userMap);

    }
    /**
     * 存储角色信息到redis
     * @param userInfo
     */
    public void setRoles(UserInfo userInfo){
        redisclient.lTrim(SystemCode.USER_PERMISSIONS+userInfo.getUserName(),1,0);
        redisclient.lTrim(SystemCode.USER_ROLES_PERMISSIONS+userInfo.getUserName(),1,0);
        List<UserRoleRelation> list = userRoleRelationMapper.getByuserId(userInfo.getId());
        for (int i = 0; i < list.size(); i++) {
            UserRoleRelation userRoleRelation = list.get(i);
            //判断用户是否是管理员身份，如果是管理员则标记
            if(SystemCode.IS_ADMIN.equals(userRoleRelation.getRoleCode())){
                userInfo.setAdmin(true);
            }
            redisclient.sAdd(SystemCode.USER_ROLE+userInfo.getUserName(),userRoleRelation.getRoleId());

            //存储权限信息到redis
            List<RoleMenuRelation> menuByRoleIds = roleMenuRelationMapper.getMenuByRoleId(userRoleRelation.getRoleId());
            List<String> permission = menuByRoleIds.stream().filter(roleMenuRelation -> roleMenuRelation.getPermissions()!=null).map(RoleMenuRelation::getPermissions).collect(Collectors.toList());
            List<String> menu = menuByRoleIds.stream().map(RoleMenuRelation::getMenuId).map(String::valueOf).collect(Collectors.toList());
            if(permission.size()>0){
                //每个用户对应的权限标识
                redisclient.lLeftPushAll(SystemCode.USER_PERMISSIONS+userInfo.getUserName(),permission);
                //每个用户对应的权限id
                redisclient.lLeftPushAll(SystemCode.USER_ROLES_PERMISSIONS+userInfo.getUserName(),menu);
            }
        }
    }
}
